<?php

namespace App\Repos;

use App\Models\Post;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Cache;


class PostRepo
{
    protected $post;
    const POST_POPULAR_REDIS = 'post_popular_redis';
    const POST_REDIS = 'post_redis';

    public function __construct(Post $post)
    {
        $this->post = $post;
        $this->trendingPostsKey = 'post_popular_key';
    }

    public function getById(int $id, array $columns = ['*'])
    {
        // $cacheKey = self::POST_REDIS . '_' . $id;
        // if (Redis::exists($cacheKey)) {
        //     return unserialize(Redis::get($cacheKey));
        // }
        
        $post = $this->post->select($columns)->find($id);
        // $post->increment('views');
        if (!$post) {
            return null;
        }
        //设置string类型的redis缓存，缓存时间1小时，本来方法为set,setex方法可以额外设置过期时间
        // Redis::setex($cacheKey, 1 * 60 * 60, serialize($post));  // 缓存 1 小时
        return $post;
    }

    public function getByManyId(array $ids, array $columns = ['*'], callable $callback = null)
    {
        $query = $this->post->select($columns)->whereIn('id', $ids);
        if ($query) {
            $query = $callback($query);
        }
        return $query->get();
    }

    public function addViews(Post $post)
    {
        // 推送消息数据到队列，通过异步进程处理数据库更新
        Redis::rpush('post-views-increment', $post->id);
        // $post->increment('views');
        return ++$post->views;
        // $post->increment('views');
        // if ($post->save()) {
        //     // 将当前文章浏览数 +1，存储到对应 Sorted Set 的 score 字段
        //     Redis::zincrby(self::POST_POPULAR_REDIS, 1, $post->id);
        // }
        // return $post->views;
    }

    // 热门文章排行榜
    public function trending($num = 10)
    {
        $cacheKey = self::POST_POPULAR_REDIS . '_' . $num;
        if (Redis::exists($cacheKey)) {
            return unserialize(Redis::get($cacheKey));
        }
        $postIds = Redis::zrevrange(self::POST_POPULAR_REDIS, 0, $num - 1);
        if (!$postIds) {
            return null;
        }
        $idsStr = implode(',', $postIds);
        $posts = $this->getByManyId($postIds, ['*'], function ($query) use ($idsStr) {
            return $query->orderByRaw('field(`id`, ' . $idsStr . ')');
        });
        Redis::setex($cacheKey, 10 * 60, serialize($posts));  // 缓存 10 分钟
        return $posts;
    }
}
